     1                                  [bits 16]
     2                                  [org 0x7c00]
     3                                  
     4 00000000 FA                      cli
     5 00000001 EB1E                    jmp load32
     6                                  
     7                                  ; GDT descriptor
     8                                  gdt_descriptor:
     9 00000003 1700                    dw gdt_end - gdt_start - 1
    10 00000005 [09000000]              dd gdt_start
    11                                  
    12                                  ; GDT
    13                                  gdt_start:
    14                                  ; Null descriptor
    15 00000009 00000000                dd 0
    16 0000000D 00000000                dd 0
    17                                  
    18                                  ; Code descriptor
    19                                  .Code: equ $ - gdt_start
    20 00000011 FFFF                    dw 0xFFFF ; limit 0-15
    21 00000013 0000                    dw 0 ; base 0-15
    22 00000015 00                      db 0 ; base 16-23
    23                                  
    24                                  ;Access Byte https://wiki.osdev.org/Global_Descriptor_Table#Segment_Descriptor
    25                                  ;7	6	5	4	3	2	1	0
    26                                  ;P	DPL		S	E	DC	RW	A
    27 00000016 9B                      db 0x9B ; 10011011b
    28                                  
    29                                  ;Flags
    30                                  ;3	2	1	0
    31                                  ;G	DB	L	Reserved
    32 00000017 CF                      db 0xCF ; limit 16-19 and flags 0-3 11001111b limit = 0xf
    33 00000018 00                      db 0 ; base 24-31
    34                                  
    35                                  ; Data descriptor
    36                                  .Data: equ $ - gdt_start
    37 00000019 FFFF                    dw 0xFFFF
    38 0000001B 0000                    dw 0
    39 0000001D 00                      db 0
    40 0000001E 93                      db 0x93 ; 10010011b
    41 0000001F CF                      db 0xCF
    42 00000020 00                      db 0
    43                                  
    44                                  gdt_end:
    45                                  
    46                                  load32:
    47                                  ; Load the GDT
    48 00000021 0F0116[0300]            lgdt [gdt_descriptor]
    49                                  
    50                                  ; Set the PE bit in CR0
    51 00000026 0F20C0                  mov eax, cr0
    52 00000029 6683C801                or eax, 1
    53 0000002D 0F22C0                  mov cr0, eax
    54                                  
    55                                  ; Jump to 32-bit code
    56 00000030 EA[3500]0800            jmp 0x08:BEGIN_32BIT
    57                                  
    58                                  [bits 32]
    59                                  BEGIN_32BIT:
    60                                  ; Set up the segment registers
    61 00000035 66B81000                mov ax, gdt_start.Data
    62 00000039 8ED8                    mov ds, ax
    63 0000003B 8EC0                    mov es, ax
    64 0000003D 8EE0                    mov fs, ax
    65 0000003F 8EE8                    mov gs, ax
    66 00000041 8ED0                    mov ss, ax
    67                                  
    68 00000043 EB22                    jmp load64
    69                                  
    70                                  ; GDT 64 bit descriptor
    71                                  GDT64:
    72                                  .Null: equ $ - GDT64
    73 00000045 0000000000000000        dq 0
    74                                  
    75                                  .Code: equ $ - GDT64
    76 0000004D 00000000                dw 0, 0
    77                                  ; ; Limit, Base - low
    78 00000051 009AAF00                db 0, 10011010b, 10101111b, 0
    79                                  ; ; Base - middle, Access(X/R),(Granularity |flag for 64 bit | limit 19 - 16), Base - high
    80                                  ; limit = 11110000000000000000 = 0xF0000 = 983040
    81                                  ; limit 983040 * 1024 * 4 = 4026531840 bytes segment size
    82                                  
    83                                  .Data: equ $ - GDT64
    84 00000055 00000000                dw 0,0
    85                                  ; Limit, Base - low                      
    86 00000059 00928F00                db 0, 10010010b, 10001111b, 0
    87                                  ; Base - middle, Access(R/W),Granularity, Base - high  
    88                                  
    89                                  .Pointer:
    90 0000005D 1700                    dw $ - GDT64 - 1
    91                                  ; Limit
    92 0000005F [4500000000000000]      dq GDT64
    93                                  ; Base
    94                                  
    95                                  load64:
    96                                  
    97                                  ; PML4T
    98 00000067 BF00300000              mov edi, 0x3000
    99                                  ; Base addres of top page table set to 0x3000
   100 0000006C 0F22DF                  mov cr3, edi
   101                                  
   102                                  
   103 0000006F 31C0                    xor eax, eax
   104                                  ; set eax to 0
   105                                  
   106                                  ; x86 uses a page size of 4096 bytes
   107                                  ; Each table contains 512 entries
   108                                  ; Each entry is of 8 bytes
   109                                  ; 512 * 8 = 4096 bytes (the size of page table)
   110 00000071 B900100000              mov ecx, 4096 
   111 00000076 F3AB                    rep stosd           
   112                                  ; Clear the memory.
   113 00000078 0F20D8                  mov eax, cr3
   114                                  
   115                                  ; DECLARING LAME PAGE TABLE AND CONNECTIONs
   116                                  ;  PML4T[0] -> PDPT[0] -> PDT[0] 0x4000-> PT[0] -> 2 MiB
   117                                  ;  0x3000 -> PML4T[0] -> 0x4003 
   118                                  ;  0x4000 -> PDT[0] -> 0x5003
   119                                  
   120                                  
   121                                  ; PDPT
   122 0000007B C70003400000            mov dword [eax], 0x4000 | 3  ; 2nd top level page table base address
   123 00000081 0500100000              add eax, 4096  
   124                                  
   125                                  ; PDT           
   126 00000086 C70003500000            mov dword [eax], 0x5000 | 3   ; 3rd top level page table base address
   127 0000008C 0500100000              add eax, 4096   
   128                                  
   129                                  ; PT
   130 00000091 C70003600000            mov dword [eax], 0x6000 | 3     ; page table base address
   131 00000097 0500100000              add eax, 4096             
   132                                  
   133                                  ; first page
   134 0000009C BB03000000              mov ebx, 0x00000003          ; Set the B-register to 0x00000003.
   135                                  
   136 000000A1 B900020000              mov ecx, 512
   137                                  
   138                                  ; Initialise Pages for first 2MiB
   139                                  ; At present eax points to base address of PT.
   140                                  SetPageEntry:
   141 000000A6 8918                    mov dword [eax], ebx                   
   142 000000A8 83C008                  add eax, 8      ; each page entry is of 8 bytes
   143 000000AB 81C300100000            add ebx, 0x1000  
   144 000000B1 E2F3                    loop SetPageEntry             
   145                                  
   146                                  
   147 000000B3 B9800000C0              mov ecx, 0xC0000080          
   148 000000B8 0F32                    rdmsr
   149                                  ; Read MSR specified by ECX into EDX:EAX.                   
   150 000000BA 0D00010000              or eax, 1 << 8               
   151 000000BF 0F30                    wrmsr   
   152                                  
   153                                  ; Will set PAE bit (which the bit 5) in CR4
   154 000000C1 0F20E7                  mov edi, cr4                
   155 000000C4 83CF20                  or edi, 1 << 5               
   156 000000C7 0F22E7                  mov cr4, edi    
   157                                  
   158                                  ; Eanble PG-bit in CR0 which is the 31 bit
   159 000000CA 0F20C7                  mov edi, cr0              
   160 000000CD 81CF00000080            or edi, 1 << 31             
   161 000000D3 0F22C7                  mov cr0, edi
   162                                  
   163 000000D6 0F0115[5D000000]        lgdt [GDT64.Pointer]
   164 000000DD EA[E4000000]0800        jmp GDT64.Code:real_long_mode
   165                                  
   166                                  [bits 64]
   167                                  real_long_mode:
   168 000000E4 66B81000                mov ax, GDT64.Data
   169 000000E8 8ED8                    mov ds, ax
   170 000000EA 8EC0                    mov es, ax
   171 000000EC 8EE0                    mov fs, ax
   172 000000EE 8EE8                    mov gs, ax
   173 000000F0 8ED0                    mov ss, ax
   174 000000F2 E806000000              call print_hello
   175 000000F7 EB02                    jmp kernel
   176                                  exit:
   177 000000F9 EBFE                    jmp exit
   178                                  kernel:
   179                                  ;kernel code here
   180                                  
   181 000000FB EBFC                    jmp exit
   182                                  
   183                                  print_hello:
   184 000000FD BF00800B00              mov edi, 0xB8000              ; Set the destination index to 0xB8000.
   185 00000102 48B8201F201F201F20-     mov rax, 0x1F201F201F201F20   ; Set the A-register to 0x1F201F201F201F20.
   185 0000010B 1F                 
   186 0000010C B9F4010000              mov ecx, 500                  ; Set the C-register to 500.
   187 00000111 F348AB                  rep stosq                     ; Clear the screen.
   188                                  
   189                                  ; Display "Hello World! AsmWave OS."
   190 00000114 BF00800B00              mov edi, 0x00b8000
   191                                  
   192 00000119 48B8481F651F6C1F6C-     mov rax, 0x1F6C1F6C1F651F48
   192 00000122 1F                 
   193 00000123 67488907                mov [edi],rax
   194                                  
   195 00000127 48B86F1F201F571F6F-     mov rax, 0x1F6F1F571F201F6F
   195 00000130 1F                 
   196 00000131 6748894708              mov [edi + 8], rax
   197                                  
   198 00000136 48B8721F6C1F641F21-     mov rax, 0x1F211F641F6C1F72
   198 0000013F 1F                 
   199 00000140 6748894710              mov [edi + 16], rax
   200                                  
   201 00000145 48B8201F411F731F6D-     mov rax, 0x1F6D1F731F411F20
   201 0000014E 1F                 
   202 0000014F 6748894718              mov [edi + 24], rax
   203                                  
   204 00000154 48B8571F611F761F65-     mov rax, 0x1F651F761F611F57
   204 0000015D 1F                 
   205 0000015E 6748894720              mov [edi + 32], rax
   206                                  
   207 00000163 48B8201F4F1F531F2E-     mov rax, 0x1F2E1F531F4F1F20
   207 0000016C 1F                 
   208 0000016D 6748894728              mov [edi + 40], rax
   209                                  
   210 00000172 C3                      ret
   211                                  
   212                                  ; Padding
   213 00000173 00<rep 8Bh>             times 510 - ($-$$) db 0
   214                                  
   215                                  ; Magic number
   216 000001FE 55AA                    dw 0xaa55
